/**
 *  Copyright (c) 2010-2011, Monash e-Research Centre
 * (Monash University, Australia)
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 * * Neither the name of the Monash University nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.multipart.*;

/** 
 * A servlet class for parsing a submitted History of Adoption Web Form
 * and sending the results to MediaFlux.
 *
 * @author Grischa Meyer
 * @author Steve Androulakis
 */
public class Submit extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public Submit() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	public static File createTempDirectory() throws IOException {
		final File temp;

		temp = File.createTempFile("temp", Long.toString(System.nanoTime()));

		if (!(temp.delete())) {
			throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
		}

		if (!(temp.mkdir())) {
			throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
		}

		return (temp);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();

		try {
			// Get the inputStream
			InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("setup.properties");

			Properties properties = new Properties();

			// System.out.println("InputStream is: " + inputStream);

			// load the inputStream using the Properties
			properties.load(inputStream);

			// get the value of the property
			String host = properties.getProperty("mediaflux.server.host");
			int port = Integer.parseInt(properties.getProperty("mediaflux.server.port"));
			String domain = properties.getProperty("mediaflux.server.domain");
			String user = properties.getProperty("mediaflux.username");
			String password = properties.getProperty("mediaflux.password");
			String basenamespace = properties.getProperty("mediaflux.basenamespace");

			boolean useSSL = Boolean.parseBoolean(properties.getProperty("mediaflux.server.useSSL"));
			boolean encrypt = Boolean.parseBoolean(properties.getProperty("mediaflux.server.encrypt"));

			MultipartParser mp = new MultipartParser(request, 2000 * 1024 * 1024); // 1MB
			Part part;
			String paramList = "";
			String storyFilename = ""; // ensure exists
			String storynamespace = "noFile";
			String email = "";

			while ((part = mp.readNextPart()) != null) {
				String name = part.getName();
				if (part.isParam()) {
					// it's a parameter part
					ParamPart paramPart = (ParamPart) part;
					String value = paramPart.getStringValue();
					// out.println("param; name=" + name + ", value=" +
					// value);
					paramList = paramList + "\n" + "param; name=" + name + ", value=" + value;

					if (name.equals("email")) {
						System.out.println("email found");
						email = value;
					}
				} else if (part.isFile()) {
					// it's a file part
					FilePart filePart = (FilePart) part;
					String fileName = filePart.getFileName();
					if (fileName != null) {
						// the part actually contained a file
						File tempDir = createTempDirectory();

						long size = filePart.writeTo(tempDir);
						// out.println("file; name=" + name + "; filename="
						// + fileName + ", filePath=" +
						// filePart.getFilePath() + ", content type="
						// + filePart.getContentType() + ", size=" + size);

						storyFilename = fileName;

						try {

							MediafluxConfig mfConfig = new MediafluxConfig(host, port, domain, user, password, useSSL, encrypt);
							MediafluxClient mfClient = new MediafluxClient(mfConfig);

							storynamespace = fileName;

							int i = 0;
							while (mfClient.collectionExists(basenamespace, storynamespace)) {
								storynamespace = fileName + String.valueOf(i++);
							}

							mfClient.createAsset("file://" + tempDir.getAbsolutePath() + File.separator + fileName, basenamespace + "/" + storynamespace,
									"HoA Submission: " + fileName, fileName);

						} catch (Throwable t) {
							t.printStackTrace();
						}

					}
				} else {
					// the field did not contain a file
					// out.println("file; name=" + name + "; EMPTY");
				}

			}

			MediafluxConfig mfConfig = new MediafluxConfig(host, port, domain, user, password, useSSL, encrypt);
			MediafluxClient mfClient = new MediafluxClient(mfConfig);

			if (storyFilename.equals("")) {
				String noFile = "noFile";

				int i = 0;
				while (mfClient.collectionExists(basenamespace, storynamespace)) {
					storynamespace = noFile + String.valueOf(i++);
				}
			}

			File tempDir = createTempDirectory();
			writeMetadataToFile(paramList, tempDir);

			mfClient.createAsset("file://" + tempDir.getAbsolutePath() + File.separator + "metadata.txt", basenamespace + "/" + storynamespace,
					"HoA Submission Metadata", "metadata.txt");

			GmailSender gmailSender = new GmailSender();
			InputStream researchEmailStream = this.getClass().getClassLoader().getResourceAsStream("researcher.template");
			String researchEmailString = StreamToString.convertStreamToString(researchEmailStream);
			researchEmailString = researchEmailString.replace("___email___", email);
			researchEmailString = researchEmailString.replace("___mediafluxpath___", basenamespace + "/" + storynamespace);
			gmailSender.sendMail("History of Adoption Submission", researchEmailString);

			InputStream submissionEmailStream = this.getClass().getClassLoader().getResourceAsStream("submitter.template");
			String submissionEmailString = StreamToString.convertStreamToString(submissionEmailStream);
			submissionEmailString = submissionEmailString.replace("___principalemail___", gmailSender.to);
			gmailSender.sendMail("History of Adoption Submission Confirmation", submissionEmailString, email);

			out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> "
							+ "<html xmlns=\"http://www.w3.org/1999/xhtml\"> "
							+ "<head> "
							+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" /> "
							+ "<title>Thank you: History of Adoption in Australia</title> "
							+ "<meta name=\"robots\" content=\"noindex,nofollow\" /> "
							+ "<link href=\"static/form-style.css\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\" /> "
							+ "</head> "
							+ "<body> "
							+ "<div id=\"header\"> "
							+ "  <h1>History of Adoption in Australia</h1> "
							+ "  <div id=\"logos\"><img src=\"static/logo-monash.jpg\" alt=\"Monash University logo\" name=\"logo_monash\" width=\"208\" height=\"34\" id=\"logo_monash\" /><br /> "
							+ "    <img src=\"static/acu-logo.jpg\" width=\"248\" height=\"35\" alt=\"Australian Catholic University logo\" id=\"logo_acu\" /></div> "
							+ "  <div class=\"clear_both\"></div> "
							+ "</div> "
							+ "<div id=\"content\"> "
							+ "  <h2>Thank you</h2> "
							+ "  <p>Thank for contributing to the making of the History of Adoption in Australia. </p> "
							+ "  <p>A copy of your consent agreement has been emailed to you. You should also download and save the <a href=\"static/explanatory-statement.pdf\">Explanatory Statement [PDF file]</a>.</p> "
							+ "  <p> The principal researcher has been notified about the submission and will be in contact shortly.</p> "
							+ "  <p>We will then edit your story to remove any material which may infringe privacy legislation. You will be provided with a password which will give you, and you alone, access to an edited, online version of your story.</p> "
							+ "  <p>When you have accessed your story you will have ten days to let us know whether or not you are happy for that version to be made available to the general public. And after that, a year to change your mind.</p> "
							+ "  <hr /> " + "  <p><a href=\"http://www.arts.monash.edu.au/historyofadoption/\">Return to the History of Adoption site</a></p> "
							+ "</div> " + "</body> " + "</html>");
			// out.flush();
		}

		catch (Throwable e) {
			// display stack trace in the browser
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			response.setContentType("text/html");
			e.printStackTrace(printWriter);
			out.println("<strong>Oops!</strong><br/><br/>An error has occurred. Technical details are as follows:</br><br/><font face=\"Courier New\" size=\"2\">" + stringWriter.toString() + "</font>");
		}

	}

	private static void writeMetadataToFile(String metadata, File dir) {
		try {
			BufferedWriter out = new BufferedWriter(new FileWriter(dir.getAbsolutePath() + File.separator + "metadata.txt"));
			out.write(metadata);
			out.close();
		} catch (IOException e) {
			// System.out.println("Exception ");

		}

	} // main ends here.

}
